﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GameLibrary
{
    [Serializable]
    public class AdjancencyList<T1,T2>
    {
        #region variable

        /// <summary>
        /// normal adjancency list
        /// </summary>
        private Dictionary<T1, HashSet<T2>> adjList;

        #endregion

        #region constructor

        public AdjancencyList()
        {
            this.adjList = new Dictionary<T1, HashSet<T2>>();
        }
        public AdjancencyList(AdjancencyList<T1,T2> list)
        {
            this.adjList = new Dictionary<T1, HashSet<T2>>(list.adjList);
        }

        #endregion

        #region contains key

        public bool ContainsKey(T1 key)
        {
            return this.adjList.ContainsKey(key);
        }

        #endregion

        #region Add key & value

        public void AddKey(T1 key)
        {
            if (this.adjList.ContainsKey(key) == false)
                this.adjList.Add(key, new HashSet<T2>());
        }

        public void AddValue(T1 key, T2 value)
        {
            if (this.adjList.ContainsKey(key) == true)
                this.adjList[key].Add(value);
            else            
                this.adjList.Add(key, new HashSet<T2>(){value});
        }

        #endregion

        #region remove key & value

        public bool RemoveKey(T1 key)
        {
            if (this.adjList.ContainsKey(key) == true)
            {
                this.adjList.Remove(key);
                return true;
            }
            else
                return false;
        }

        public bool RemoveValue(T1 key, T2 value)
        {
            if (this.adjList.ContainsKey(key) == false)
                return false;
            else
                if (this.adjList[key].Contains(value) == false)
                    return false;
                else
                {
                    this.adjList[key].Remove(value);
                    return true;
                }
        }

        #endregion

        #region keys & values

        public IEnumerable<T1> Keys
        {
            get
            {
                return this.adjList.Keys;
            }
        }

        public IEnumerable<T2> Values(T1 key)
        {
            return this.adjList[key].AsEnumerable();
        }

        #endregion
    }
}
